package com.csmarket.csmarketbackend.server;

import com.csmarket.csmarketbackend.config.WebSocketConfigurator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/message" , configurator = WebSocketConfigurator.class)
@Component
public class WebSocketEndPoint {
    @Getter
    private static Set<String> onlineUsers = ConcurrentHashMap.newKeySet();// 用于存储在线用户
    private static final Logger logger = LoggerFactory.getLogger(WebSocketEndPoint.class);// 创建日志记录器
    private static final ConcurrentHashMap<String, Session> userSessions = new ConcurrentHashMap<>();// 用于存储用户名和对应的Session
    private static final ObjectMapper objectMapper = new ObjectMapper(); // JSON处理
    private static final String PUBLIC_TOPIC = "Public"; // 公共广播目标标识
    private Session session;
    private String username;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        this.session = session;
        this.username = (String) config.getUserProperties().get("username");

        if (this.username != null) {
            userSessions.put(this.username, session);
            onlineUsers.add(this.username);
            System.out.println("用户 " + username + " 已上线");

            broadcastOnlineUsers();
        } else {
            try {
                session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "未授权的访问"));
            } catch (IOException e) {
                logger.error("Error closing WebSocket session: {}", e.getMessage());
            }
        }
    }

    @OnMessage
    public void onMessage(String message) {
        if (username != null) {
            System.out.println("收到来自用户 " + username + " 的消息: " + message);
            // 处理消息逻辑
            handleMessage(message);
        }


    }

    private void handleMessage(String message) {
        try {
            // 尝试解析为JSON格式
            JsonNode jsonNode = objectMapper.readTree(message);// 尝试将JSON字符串解析为JsonNode对象

            // 获取目标用户
            String targetUser = jsonNode.get("target").asText();// 这段代码用于从JSON消息中提取目标用户信息。如果JSON中包含target字段，则将其值作为目标用户；否则，默认使用公共广播标识PUBLIC_TOPIC
            // 获取实际消息内容
            String content = jsonNode.get("content").asText();//这段代码用于从JSON消息中提取content字段的内容。如果存在content字段，则获取其文本值；否则使用原始消息字符串作为内容。

            if (PUBLIC_TOPIC.equals(targetUser)) {
                // 公共广播
                broadcastMessageToAll(username + ": " + content);
            } else {
                sendPrivateMessage(targetUser, content);
            }
        } catch (Exception e) {
            // 如果不是JSON格式，直接报错
            logger.error("Error parsing message: {}", e.getMessage());
        }
    }

    private void sendPrivateMessage(String targetUser, String content) {
        // 检查目标用户是否在线
        if (!onlineUsers.contains(targetUser)) {
            // 目标用户不在线，发送错误信息给发送者
            sendMessageToUser(username, "错误：用户 " + targetUser + " 不在线");
            return;
        }

        // 发送给目标用户
        sendMessageToUser(targetUser, "[私聊] " + username + ": " + content);

        // 发送回发送者作为确认
        if (!username.equals(targetUser)) {
            sendMessageToUser(username, "[发送给 " + targetUser + "] " + content);
        }
    }

    @OnClose
    public void onClose() {
        if (username != null) {
            userSessions.remove(username);
            System.out.println("用户 " + username + " 已下线");
            onlineUsers.remove(username);

            // 通知所有用户在线列表更新
            broadcastOnlineUsers();
        }
    }
    @OnError
    public void onError(Throwable error) {
        if (username != null) {
            System.out.println("用户 " + username + " 的WebSocket发生错误: " + error.getMessage());
        }
    }

    public static void sendMessageToUser(String username, String message) {
        Session session = userSessions.get(username);
        if (session != null && session.isOpen()) {
            try {
                session.getBasicRemote().sendText(message);// 发送消息给用户
            } catch (IOException e) {
               logger.error("Error sending message to user: {}", e.getMessage());
            }
        }
    }
    public static void broadcastMessageToAll(String message) {
        for (Session session : userSessions.values()) {
            if (session.isOpen()) {
                try {
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    logger.error("Error broadcasting message to user: {}", e.getMessage());
                }
            }
        }
    }
    public static void broadcastOnlineUsers() {
        String onlineUsersList = "ONLINE_USERS:" + String.join(",", onlineUsers);
        broadcastMessageToAll(onlineUsersList);
    }
    public static int getOnlineUserCount() {
        return onlineUsers.size();
    }

}
